/*
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package eu.fastl.dragster.loadgen.impl;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * One thread which executes HTTP requests for the Load Generator
 *
 * @author Ernst Fastl
 */
public class HttpLoadGeneratorThread extends Thread {

    private static final Logger LOGGER = LoggerFactory.getLogger(HttpLoadGeneratorThread.class);

    private final HttpClient httpClient;

    private final HttpLoadGenerator generator;

    public HttpLoadGeneratorThread(HttpLoadGenerator generator) {
        this.httpClient = generator.createHttpClient();
        this.generator = generator;
    }

    @Override
    public void run() {
        LOGGER.debug("Starting Load Generator Thread");
        String url = null;
        while (null != (url = this.generator.getProvider().getNextUrl())) {
            if(this.generator.isTimeUp()){
                LOGGER.debug("Quitting Thread because time is up");
                return;
            }
            if (this.generator.getConfig().isDryRun()) {
                LOGGER.info("QUERY:" + url);
            } else {
                try {
                    queryUrl(url);
                } catch (Exception e) {
                    LOGGER.error("Could not query URL: " + url, e);
                }
            }
        }
    }

    private void queryUrl(String url) throws IOException, ClientProtocolException {

        HttpGet httpget = new HttpGet(url);
        long start = System.currentTimeMillis();
        HttpResponse response = this.httpClient.execute(httpget);
        long executionTime = System.currentTimeMillis() - start;
        HttpEntity entity = response.getEntity();

        int contentLength = 0;

        if (entity != null) {
            InputStream instream = entity.getContent();
            try {
                char[] buffer = new char[1024];
                Reader reader = new BufferedReader(new InputStreamReader(instream));
                int n;
                while ((n = reader.read(buffer)) != -1) {
                    contentLength += n;
                }
            } finally {
                instream.close();
            }
        }

        int statusCode = response.getStatusLine().getStatusCode();
        StringBuilder infoLine = new StringBuilder("HTTP_REQUEST:");
        infoLine.append(url);
        infoLine.append(" : ");
        infoLine.append(statusCode);
        infoLine.append(" : ");
        infoLine.append(executionTime);
        infoLine.append("ms");
        infoLine.append(" : ");
        infoLine.append(contentLength);
        infoLine.append(" bytes");

        this.generator.getStatistics().addValue(executionTime);
        this.generator.getRequestStatusCount(statusCode).incrementAndGet();

        LOGGER.info(infoLine.toString());
    }
}
